package com.TeacherInfoServer.listener;

import com.TeacherInfoServer.exception.JobNumberNotExistException;
import com.TeacherInfoServer.exception.RecordRepeatedException;
import com.TeacherInfoServer.pojo.DTO.TeacherDTO;
import com.TeacherInfoServer.pojo.entity.TemporaryPosition;
import com.TeacherInfoServer.pojo.excelImport.TemporaryPositionExcel;
import com.TeacherInfoServer.common.service.TeacherService;
import com.TeacherInfoServer.common.service.TemporaryPositionService;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import jakarta.validation.Validator;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Data
@Slf4j
@Component
public class TemporaryPositionListener implements ReadListener<TemporaryPositionExcel> {
    @Autowired
    private TemporaryPositionService temporaryPositionService;
    @Autowired
    private TeacherService teacherService;
    @Autowired
    private Validator validator;
    private final List<TemporaryPosition> temporaryPositionList = new ArrayList<>();
    private final List<TemporaryPosition> updateList = new ArrayList<>();
    private final List<TemporaryPosition> addList = new ArrayList<>();
    private final Set<TemporaryPositionExcel> temporaryPositionFormSet = new HashSet<>();
    private Integer record;
    @Override
    public void invoke(TemporaryPositionExcel temporaryPositionExcel, AnalysisContext analysisContext) {
        Set<ConstraintViolation<TemporaryPositionExcel>> violations = validator.validate(temporaryPositionExcel);
        if (violations.isEmpty()){
            TeacherDTO teacherDTO = teacherService.getOne(temporaryPositionExcel.getTeacherId()).getData();
            if (teacherDTO != null && teacherDTO.getTeacherName().equals(temporaryPositionExcel.getTeacherName())){
                if (!temporaryPositionFormSet.contains(temporaryPositionExcel)){
                    TemporaryPosition temporaryPosition =
                            new TemporaryPosition(null,
                                    temporaryPositionExcel.getTeacherId(),
                                    temporaryPositionExcel.getUnit(),
                                    temporaryPositionExcel.getDescription(),
                                    temporaryPositionExcel.getStartDate(),
                                    temporaryPositionExcel.getEndDate(),1,null);
                    temporaryPositionList.add(temporaryPosition);
                    temporaryPositionFormSet.add(temporaryPositionExcel);
                } else {
                    throw new RecordRepeatedException();
                }
            } else {
                if (teacherDTO == null) {
                    throw new JobNumberNotExistException();
                } else {
                    throw new RuntimeException("工号与教师名不匹配：" + teacherDTO.getTeacherId());
                }
            }
        } else {
            String errorMessage = violations.iterator().next().getMessage();
            throw new ConstraintViolationException(errorMessage, violations);
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        List<TemporaryPosition> temporaryPositions = temporaryPositionService.list();
        temporaryPositionList.forEach(temporaryPosition -> {
            Optional<TemporaryPosition> dbTemporaryPositionOptional = temporaryPositions.stream()
                    .peek(dbTemporaryPosition -> dbTemporaryPosition.setId(null))
                    .filter(temporaryPosition::equals)
                    .findFirst();
            dbTemporaryPositionOptional.ifPresent(dbTemporaryPosition -> log.info("记录已存在数据库:{}",dbTemporaryPosition));
            if (dbTemporaryPositionOptional.isEmpty()) {
                addList.add(temporaryPosition);
            }
        });
        List<TemporaryPosition> mergedList = Stream.concat(updateList.stream(), addList.stream())
                .collect(Collectors.toList());
        temporaryPositionService.saveOrUpdateBatch(mergedList);
        setRecord(mergedList.size());
        initList();
    }
    public void initList(){
        temporaryPositionList.clear();
        updateList.clear();
        addList.clear();
        temporaryPositionFormSet.clear();
    }
}
